Skip to content

Closes #17598: Add bulk creation for VLANs#22377

Open
pheus wants to merge 1 commit into
mainfrom
17598-bulk-create-of-vlans
Open

Closes #17598: Add bulk creation for VLANs#22377
pheus wants to merge 1 commit into
mainfrom
17598-bulk-create-of-vlans

Conversation

@pheus

@pheus pheus commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Closes: #17598

This adds bulk VLAN creation using NetBox’s existing bulk-create pattern.

Users can now create multiple VLANs from a comma-separated list or range of VLAN IDs, for example 100,200-210,3100-3299. The VLAN name field also supports a {vid} placeholder, allowing generated names such as Customer-3100, Customer-3101, and so on.

The implementation keeps the single VLAN create form unchanged and reuses the generic BulkCreateView flow, with a small generic extension for applying generated pattern values to additional form fields.

@pheus

pheus commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

@claude /review Only report on issues of potential concern; we don't need commentary on anything that doesn't require further consideration.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Claude finished @pheus's task in 3m 33s —— View job


PR Review: Bulk VLAN Creation

  • Read changed files
  • Analyze for issues of concern
  • Post findings

Issues of Concern

1. Misleading test: test_bulk_add_vlans_rejects_ids_outside_group_ranges

test_views.py:1552 — The test creates a group with NumericRange(200, 203), which is a half-open PostgreSQL interval [200, 203), meaning valid VIDs are 200, 201, 202 (not 203). The submitted pattern '200-203' generates VIDs 200, 201, 202 (all valid) and 203 (outside the range). The test passes because VID 203 fails validation and triggers a rollback — but the test name and intent suggest the entire pattern is "outside" the group ranges, which is not the case.

A clearer test would use a pattern entirely outside the valid range (e.g., 500-502 against NumericRange(200, 204)) or add a comment explaining the half-open semantics. As written, this test has a fragile dependency on a subtle PostgreSQL boundary that will likely confuse future maintainers. Fix this →%2C%20meaning%20VIDs%20200-202%20are%20valid%20and%20203%20is%20not.%20The%20pattern%20200-203%20only%20has%20one%20VID%20outside%20the%20range%20(203).%20Either%20rename%20the%20test%20to%20test_bulk_add_vlans_rolls_back_when_any_vid_outside_group_range%20and%20add%20a%20comment%20explaining%20the%20half-open%20semantics%2C%20or%20rewrite%20to%20use%20a%20pattern%20entirely%20outside%20the%20valid%20range.&repo=netbox-community/netbox)

2. Undocumented {value} placeholder

bulk_views.py:254-266get_pattern_context registers both {value} and {vid} as substitution keys, but only {vid} is mentioned in the user-facing help text (model_forms.py:746). Either document {value} in the help text or remove it from the context to avoid confusion. Fix this →

3. No limit on batch size

bulk_views.py:342 / forms/bulk_create.py:19 — A user can specify a pattern covering the full VLAN range (e.g., 1-4094) and create 4094 objects in a single POST with no server-side cap. The _create_objects loop instantiates a ModelForm, runs full validation, and saves each object individually — no bulk insert. For large patterns this will be slow and could tie up a worker for an extended period. Worth considering a limit (e.g., 1000 per request) or at minimum documenting the scale expectation.

4. IntegrityError used as transaction-abort sentinel (pre-existing, but extended here)

bulk_views.py:356 — Using raise IntegrityError() to break out of the loop and abort an atomic() block is fragile: it conflates a deliberate control-flow signal with a real database integrity violation. Any upstream code that catches IntegrityError broadly (e.g., in middleware or a wrapper) would misinterpret this. This pattern was pre-existing, but this PR significantly extends _create_objects and add_model_form_errors around it, making it a larger surface. This should ideally be replaced with a flag variable and an explicit transaction.savepoint_rollback(), but that's a larger refactor.


@pheus pheus force-pushed the 17598-bulk-create-of-vlans branch from 41df9d7 to 29acf82 Compare June 4, 2026 12:57
@pheus

pheus commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

@claude /review

Point 1, 2 and 4 are addressed.

For the batch-size concern, I agree it’s worth considering, but I’m inclined not to add a hard limit in this PR unless review prefer one. The possible VLAN range is bounded by 1-4094, and adding a generic limit to BulkCreateView could affect existing prefix/IP address bulk-create behavior. If we do want a limit, I’d suggest adding it as a generic opt-in, e.g. max_pattern_values = None, and setting it only where desired.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Claude finished @pheus's task in 1m 37s —— View job


PR Review: Bulk VLAN Creation (Re-review)

  • Read changed files
  • Verify points 1, 2, and 4 are addressed
  • Evaluate batch-size concern
  • Post findings

All three previously flagged issues are addressed:

Point 1 — Test renamed and pattern made unambiguous (test_views.py:1552): The test is now test_bulk_add_vlans_rolls_back_when_any_id_outside_group_range, uses NumericRange(200, 204) with an explanatory comment # Valid VIDs: 200-203, and the pattern '200-203,500' unambiguously includes one VID (500) entirely outside the group range. Clean.

Point 2 — {value} placeholder removed (bulk_views.py:254-264): get_pattern_context now returns {self.pattern_target: str(value)} — the key is 'vid', not a separate undocumented 'value' key. The help text and the actual substitution keys are now aligned.

Point 4 — AbortTransaction replaces IntegrityError sentinel (bulk_views.py:354): raise AbortTransaction() is used to break the loop and roll back. The except clause at line 425 handles both (AbortTransaction, IntegrityError), so genuine DB integrity errors are still caught correctly.

Point 3 — Batch size: The argument against a hard limit is sound for this PR. VIDs are spec-bounded to 1–4094, so the worst-case batch is 4093 objects — large but finite and known. Introducing max_pattern_values = None as an opt-in class attribute if limits are ever needed for other BulkCreateView subclasses is the right approach. No action required here.

One minor observation worth noting: parse_numeric_range already deduplicates via sorted(set(values)), so a pattern like 100,100-102 would produce [100, 101, 102] rather than a duplicate-VID error. This is fine behavior, but it's worth being aware of if the VLAN model has a unique constraint on (group, vid) that would otherwise surface a confusing integrity error.

No blocking issues. The PR looks good to merge from a code-quality standpoint.

Implements bulk VLAN creation with pattern-based VID generation and
template field support. Users can specify VLAN ID ranges
(e.g., 100,200-210) and use {vid} placeholders in fields like name.

Fixes #17598
@pheus pheus force-pushed the 17598-bulk-create-of-vlans branch from 29acf82 to cee5263 Compare June 4, 2026 13:51
@pheus pheus marked this pull request as ready for review June 4, 2026 13:54
@pheus pheus requested review from a team and jnovinger and removed request for a team June 4, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bulk create of VLANs

1 participant